package com.fancy.application.sys.auth.config;

import com.auth0.jwt.exceptions.TokenExpiredException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fancy.application.common.utils.JwtUtil;
import com.fancy.application.sys.org.entity.SysOrgPerson;
import com.fancy.application.sys.org.service.ISysOrgPersonService;
import com.fancy.application.sys.permission.service.ISysPermissionRoleService;
import lombok.extern.log4j.Log4j2;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import javax.annotation.Resource;
import java.util.List;

/**
 * Created by wison on 2019/8/27.
 */
@Log4j2
public class MyRealm extends AuthorizingRealm {

    @Resource
    private ISysOrgPersonService sysOrgPersonService;
    @Resource
    private ISysPermissionRoleService sysPermissionRoleService;
    @Resource
    private JwtUtil jwtUtil;

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo simpleAuthentizationInfo = new SimpleAuthorizationInfo();
        String token  = (String)principals.getPrimaryPrincipal();
        SysOrgPerson person = sysOrgPersonService.getPersonByToken(token);
        List<String> roles = sysPermissionRoleService.getResByUser(person);
        simpleAuthentizationInfo.addStringPermissions(roles);
        return simpleAuthentizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String token = (String) authenticationToken.getCredentials();
        // 解密获得username，用于和数据库进行对比
        String username = jwtUtil.getUsername(token);
        if (username == null) {
            throw new AuthenticationException("token无效");
        }
        QueryWrapper<SysOrgPerson> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("fd_login_name",username).eq("fd_is_avaliable",true);
        SysOrgPerson sysOrgPerson = sysOrgPersonService.getOne(queryWrapper);
        if (sysOrgPerson == null) {
            throw new AuthenticationException("用户名或密码错误!");
        }

        try {
            jwtUtil.verify(token, username, sysOrgPerson.getFdPassword());
        } catch (TokenExpiredException e) {
            throw new AuthenticationException("token已失效!");
        } catch (Exception e) {
            throw new AuthenticationException("用户名或密码错误!");
        }

        return new SimpleAuthenticationInfo(token, token, "my_realm");
    }
}
